﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;
using System.Net;
using System.IO;
using System.Xml;
using System.Threading;

namespace ServBus.ListForm2010.Utility
{
    public class SPUtility
    {
        private static string mWebFullUrl;


        public static string CreateFile(SPSite site, SPWeb web, SPList list, string fldNam, string fileName, byte[] ct)
        {
            web.AllowUnsafeUpdates = true;
            SPFolder folder = web.GetFolder(list.RootFolder.ServerRelativeUrl + "/" + fldNam);
            if (!folder.Exists)
            {
                try
                {
                    list.RootFolder.SubFolders.Add(fldNam);
                    list.Update();
                }
                catch (Exception ex)
                { }
            }
            SPFile m_file = web.GetFile(folder.Url + "/" + fileName);

            if (m_file != null)
            {
                m_file.Delete();
            }

            web.Files.Add(folder.ServerRelativeUrl + "/" + fileName, ct);

            return web.Url + "/" + folder.Url + "/" + fileName;
        }

        public static void CreateFileUnderDocLib(SPWeb web, SPList docLib, string fileName, byte[] ct)
        {
            string path = "/sites/testinfo/FormLib";
            SPFolder m_folder = web.GetFolder(path);
            SPFile file = web.GetFile(path + "/" + fileName);
            if (file.Exists)
            {
                file.Delete();
            }
            m_folder.Files.Add(path + "/" + fileName, ct);
        }

        public static void CreateFolder(SPList list, string fldNam)
        {
            list.RootFolder.SubFolders.Add(fldNam);
        }

        //private static listService.Lists GetListSercie(SPWeb web)
        //{
        //    if (mListService == null)
        //    {
        //        mListService = new listService.Lists();
        //        mListService.Credentials = CredentialCache.DefaultCredentials;
        //        mListService.Url = GetWebFullUrl(web) + "_vti_bin/lists.asmx";
        //        mListService.Credentials = System.Net.CredentialCache.DefaultCredentials;
        //    }

        //    return mListService;
        //}

        public static bool HasLookupIndexToList(SPList mainList, SPList subOrdList)
        {
            foreach (SPField field in subOrdList.Fields)
            {
                if (field is SPFieldLookup)
                {
                    SPFieldLookup lkpFld = field as SPFieldLookup;
                    if (!string.IsNullOrEmpty(lkpFld.LookupList)
                        && lkpFld.LookupList.ToLower().Contains(mainList.ID.ToString().ToLower()))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public void UploadFileToSPList(string filePath, SPWeb web, SPList list)
        {

        }

        public static void AddContenttype(string ctNam, SPWeb web, string listTitle)
        {
            SPList list = web.Lists[listTitle];
            SPContentType ct = web.ContentTypes[ctNam];
            try
            {

                list.ContentTypes.Add(ct);
                list.Update();
            }
            catch { }
        }

        /// <summary>
        /// 设置列表的默认内容类型
        /// </summary>
        /// <param name="list"></param>
        /// <param name="ctName"></param>
        public static void SetDfaultContentType(SPList list, string ctName)
        {
            System.Collections.Generic.IList<SPContentType> currentOrder =
                     new System.Collections.Generic.List<SPContentType>();
            currentOrder = list.RootFolder.ContentTypeOrder;

            IList<SPContentType> result = new List<SPContentType>();
            foreach (SPContentType ct in currentOrder)
            {
                if (ct.Name == ctName)
                {
                    result.Add(ct);
                }
            }
            foreach (SPContentType ct in currentOrder)
            {
                if (ct.Name != ctName)
                {
                    result.Add(ct);
                }
            }

            list.RootFolder.UniqueContentTypeOrder = result;
            list.RootFolder.Update();
        }

        public static void CreateDocumentLib(SPWeb web, string title)
        {
            //splist

            web.Lists.Add(title, null, SPListTemplateType.DocumentLibrary);
            web.Update();
        }

        //public static void ClearAllItemsInFolder(SPList list, SPFolder folder)
        //{
        //    List<SPListItem> items = new List<SPListItem>();

        //    foreach (SPListItem item in list.Items)
        //    {
        //        if (item.Url.Remove(item.Url.LastIndexOf('/')) == folder.Url)
        //        {
        //            items.Add(item);
        //        }
        //    }


        //    for (int i = 0; i < items.Count; ++i)
        //    {
        //        XmlElement ele = new XmlDocument().CreateElement("Batch");
        //        ele.SetAttribute("OnError", "Return");

        //        string ct = "<Method ID='1' Cmd='Delete'><Field Name='ID'>" + items[i].ID + "</Field ></Method>";
        //        ele.InnerXml = ct;

        //        XmlNode node = GetListSercie(list.ParentWeb).UpdateListItems(list.Title, ele);
        //    }

        //}

        //public static void AddFileToListItem(SPList list, SPListItem item, string name, byte[] bytes)
        //{
        //    GetListSercie(list.ParentWeb).AddAttachment(list.Title, item.ID.ToString(), name, bytes);
        //}

        private static string GetWebFullUrl(SPWeb web)
        {
            string url = web.Site.Url;
            return url.Trim('/') + "/";
        }


        //public static SPListItem CreateItemUnderFolder(SPList list, SPFolder folder, Dictionary<string, string> fieldValues)
        //{
        //    string specFldUrl = GetWebFullUrl(list.ParentWeb) + folder.Url;
        //    XmlDocument doc = new XmlDocument();
        //    XmlElement batch = doc.CreateElement("Batch");
        //    batch.SetAttribute("OnError", "Continue");
        //    batch.SetAttribute("RootFolder", specFldUrl);


        //    string qstr = "<Method ID='1' Cmd='New'><Field Name='ID'>New</Field>";
        //    foreach (string fldName in fieldValues.Keys)
        //    {
        //        qstr += "<Field Name='" + fldName + "'>" + fieldValues[fldName] + "</Field>";
        //    }

        //    qstr += "</Method>";

        //    batch.InnerXml = qstr;
        //    XmlNode node = GetListSercie(list.ParentWeb).UpdateListItems(list.Title, batch);
        //    XmlDocument responseXml = new XmlDocument();
        //    responseXml.LoadXml(node.OuterXml);
        //    XmlNodeList nodeLists = responseXml.GetElementsByTagName("z:row");
        //    string id = nodeLists[0].Attributes["ows_ID"].Value;

        //    return list.GetItemById(Convert.ToInt32(id));
        //}

        //public static void CreateFolderUnderList(SPWeb web, string listTitle, string folderName)
        //{
        //    //SPList list = web.Lists[listTitle];
        //    //// /sites/site4/Lists/Users/Attachments
        //    SPList list = web.Lists[listTitle];
        //    string fldurl = list.RootFolder.Url + "/defaultInfoPath";

        //    if (!web.GetFolder(web.ServerRelativeUrl + fldurl).Exists)
        //    {
        //        string xmlCommand;
        //        XmlDocument doc = new XmlDocument();
        //        xmlCommand = "<Method ID='1' Cmd='New'><Field Name='FSObjType'>1</Field><Field Name='BaseName'>DefaultInfoPath</Field> <Field Name='ID'>New</Field></Method>";
        //        XmlElement ele = doc.CreateElement("Batch");
        //        ele.SetAttribute("OnError", "Continue");
        //        ele.InnerXml = xmlCommand;
        //        XmlNode node1 = GetListSercie(web).UpdateListItems(listTitle, ele);
        //    }
        //}

        // because that the file need to be removed maybe under a specific sub folder,
        // so the param should be a folder path.
        public static void DeleteSpecialFile(SPWeb web, string listTitle, string itemName)
        {
            SPList list = web.Lists[listTitle];
            web.AllowUnsafeUpdates = true;
            foreach (SPListItem item in list.Items)
            {
                if (item.Name.ToLower() == itemName.ToLower().Substring(0, itemName.LastIndexOf(".")))
                {
                    item.Delete();
                    break;
                }
            }
            web.AllowUnsafeUpdates = false;
        }

        public static bool UploadFileToDocumentLibrary(string sourceFilePath, string targetDocumentLibraryPath)
        {
            //Flag to indicate whether file was uploaded successfuly or not
            bool isUploaded = true;
            try
            {
                // Create a PUT Web request to upload the file.
                WebRequest request = WebRequest.Create(targetDocumentLibraryPath);
                //Set credentials of the current security context
                request.Credentials = CredentialCache.DefaultCredentials;
                request.Method = "PUT";
                // Create buffer to transfer file
                byte[] fileBuffer = new byte[1024];

                // Write the contents of the local file to the request stream.
                using (Stream stream = request.GetRequestStream())
                {
                    //Load the content from local file to stream
                    using (FileStream fsWorkbook = File.Open(sourceFilePath, FileMode.Open, FileAccess.Read))
                    {
                        //Get the start point

                        int startBuffer = fsWorkbook.Read(fileBuffer, 0, fileBuffer.Length);

                        for (int i = startBuffer; i > 0; i = fsWorkbook.Read(fileBuffer, 0, fileBuffer.Length))
                        {
                            stream.Write(fileBuffer, 0, i);
                        }
                    }
                }

                WebResponse response = request.GetResponse();
                //Close response
                response.Close();
            }
            catch (Exception ex)
            {
                isUploaded = false;
            }

            //Return the final upload status
            return isUploaded;
        }

        /// <summary>
        /// 继承表单的ContentType用于发布
        /// </summary>
        /// <param name="p_cur_list_name"></param>
        /// <param name="ctName"></param>
        /// <param name="web"></param>
        public static void AddContentTypeInWeb(string p_cur_list_name, string ctName, SPWeb web)
        {
            try
            {
                ctName = "Form_" + ctName;

                SPContentType itemCt = null;

                if (1033 == Thread.CurrentThread.CurrentUICulture.LCID)
                {
                    itemCt = web.ContentTypes["Form"];
                }
                else if (2052 == Thread.CurrentThread.CurrentUICulture.LCID)
                {
                    itemCt = web.ContentTypes["表单"];
                }

                SPContentType ct = web.ContentTypes[ctName];
                if (ct != null)
                {
                    ct.Delete();
                    web.Update();
                }

                ct = new SPContentType(itemCt, web.ContentTypes, ctName);
                web.ContentTypes.Add(ct);
                web.Update();

            }
            catch (Exception ex)
            {
                WriteLog.OutLog("SPUtility", "AddContentTypeInWeb", ErrorType.ERROR_CUSTMOER, ex.Message + '\r' + '\n' + ex.ToString());
            }
        }

        /// <summary>
        /// 新建继承主表的ContentType，用于数据交互
        /// </summary>
        /// <param name="p_cur_list_name"></param>
        /// <param name="p_ct_name"></param>
        /// <param name="p_selected_ct_name"></param>
        /// <param name="p_web"></param>
        public static void AddSecContentTypeInList(InfoPathContext p_context)
        {
            try
            {
                string p_ct_name = p_context.XsnName;
                string p_selected_ct_name = p_context.SelectedContent[p_context.ListName];

                SPWeb p_web = p_context.Web;
                SPContentType m_selected_ct = p_web.ContentTypes[p_selected_ct_name];

                if (m_selected_ct != null)
                {
                    //TO DO..如果已有该ContentType，就暂不作处理
                    SPContentType m_new_ct = p_web.ContentTypes[p_ct_name];
                    if (m_new_ct != null)
                    {
                        p_context.ListContentTypeID = m_new_ct.Id.ToString();
                        p_context.ListContentTypeName = p_ct_name;
                        //m_new_ct.Delete();
                        //p_web.Update();
                    }
                    else
                    {
                        m_new_ct = new SPContentType(m_selected_ct, p_web.ContentTypes, p_ct_name);

                        string m_display_form_url = Utility.GetXmlValue("ViewFormPageUrl", p_web.Url);
                        string m_edit_form_url = Utility.GetXmlValue("EditFormPageUrl", p_web.Url);
                        string m_new_form_url = Utility.GetXmlValue("NewFormPageUrl", p_web.Url);
                        m_new_ct.DisplayFormUrl = m_display_form_url;
                        m_new_ct.EditFormUrl = m_edit_form_url;
                        m_new_ct.NewFormUrl = m_new_form_url;

                        p_web.ContentTypes.Add(m_new_ct);
                        p_web.Update();

                        //for config list
                        p_context.ListContentTypeID = m_new_ct.Id.ToString();
                        p_context.ListContentTypeName = p_ct_name;
                    }

                    SPList m_cur_list = p_web.Lists[p_context.ListName];

                    m_cur_list.RootFolder.UniqueContentTypeOrder = null;
                    m_cur_list.RootFolder.Update();

                    if (m_cur_list.ContentTypes[p_ct_name] == null)
                    {
                        m_cur_list.ContentTypesEnabled = true;

                        m_cur_list.ContentTypes.Add(m_new_ct);

                        m_cur_list.Update();
                    }

                    m_cur_list.Update();
                    //IList<SPContentType> m_ct_collection = new List<SPContentType>();
                    //foreach(SPContentType t_ct in m_cur_list.RootFolder.ContentTypeOrder)
                    //{
                    //    m_ct_collection.Add(t_ct);
                    //}
                    //m_ct_collection.Add(m_new_ct);

                    //m_cur_list.RootFolder.UniqueContentTypeOrder = m_ct_collection;

                    //m_cur_list.RootFolder.Update();
                }
            }
            catch (Exception ex)
            {
                WriteLog.OutLog("SPUtility", "AddSecContentTypeInList", ErrorType.ERROR_CUSTMOER, ex.Message + '\r' + '\n' + ex.ToString());
            }
        }

        public static List<string> GetFieldsValueInList(string listNam, SPWeb web, string fldNam)
        {
            SPList list = web.Lists[listNam];
            List<string> vals = new List<string>();

            foreach (SPListItem item in list.Items)
            {
                try
                {
                    vals.Add(item[fldNam].ToString());
                }
                catch { }
            }

            return vals;
        }

        /// <summary>
        /// 根据ContentTypeId从配置列表中获取XsnLocation
        /// </summary>
        /// <param name="p_ct_id"></param>
        /// <param name="p_web"></param>
        /// <returns></returns>
        public static string GetXsnLocationByContentType(string p_ct_id, SPWeb p_web)
        {

            string m_config_list_name = Utility.GetXmlValue("InfoPathConfiglist", p_web.Url);
            SPList m_config_list = p_web.Lists[m_config_list_name];
            string m_xsn_location = string.Empty;
            foreach (SPListItem m_item in m_config_list.Items)
            {
                string m_CTID = Convert.ToString(m_item["ContentTypeID"]);
                if (string.IsNullOrEmpty(m_CTID))
                {
                    continue;
                }
                if (p_ct_id.StartsWith(m_CTID, StringComparison.OrdinalIgnoreCase))
                {
                    m_xsn_location = Convert.ToString(m_item["XsnLocation"]);
                    break;
                }
            }

            return m_xsn_location;
        }

        /// <summary>
        /// 判断是否是Group节点
        /// </summary>
        /// <param name="p_ct_id">当前item的内容类型</param>
        /// <param name="p_name">当前节点的名称</param>
        /// <returns></returns>
        public static bool CheckIsGourp(string p_ct_id, string p_name, SPWeb p_web)
        {
            string m_config_list_name = Utility.GetXmlValue("InfoPathConfiglist", p_web.Url);
            SPList m_config_list = p_web.Lists[m_config_list_name];
            string m_xsn_location = string.Empty;
            foreach (SPListItem m_item in m_config_list.Items)
            {
                string s = Convert.ToString(m_item["ContentTypeID"]);

                if (string.IsNullOrEmpty(s))
                {
                    continue;
                }

                if (p_ct_id.StartsWith(m_item["ContentTypeID"].ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    string m_all_list = Convert.ToString(m_item["AllListNames"]);

                    string[] m_names = m_all_list.Split('|');

                    if (m_names.Contains(p_name))
                    {
                        //如果节点跟主表名称相同，同样不当作Group来处理
                        if (p_name != m_names[0])
                        {
                            return true;
                        }
                    }

                }
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="displayName"></param>
        /// <param name="staticName"></param>
        /// <param name="title"></param>
        /// <param name="description"></param>
        /// <param name="required"></param>
        /// <param name="contentType"></param>
        public static void CreateTextColumn(SPList list, string displayName, string staticName, string title, string description, bool required, string contentType)
        {
            SPFieldText field = (SPFieldText)list.Fields.CreateNewField(SPFieldType.Text.ToString(), displayName);
            field.StaticName = staticName;
            field.Title = title;
            field.Description = description;
            field.Required = required;

            list.Fields.Add(field);

            if (contentType.Equals("") == false)
            {
                list.ContentTypes[contentType].FieldLinks.Add(new SPFieldLink(list.Fields[displayName]));
                list.ContentTypes[contentType].Update();
            }

            SPView defaultView = list.DefaultView;
            defaultView.ViewFields.Add(list.Fields[displayName]);
            defaultView.Update();
        }

        /// <summary>
        /// 创建自定义列表
        /// </summary>
        /// <param name="p_web"></param>
        /// <param name="p_list_name"></param>
        public static void CreateCustomList(SPWeb p_web, string p_list_name)
        {
            p_web.Lists.Add(p_list_name, "表单配置列表", SPListTemplateType.GenericList);
        }

        /// <summary>
        /// 设置默认的内容类型
        /// </summary>
        /// <param name="p_list"></param>
        /// <param name="p_ct_name"></param>
        public static void SetDefaultContentType(SPList p_list, string p_ct_name)
        {
            IList<SPContentType> m_ct_current_order = new List<SPContentType>();
            m_ct_current_order = p_list.RootFolder.ContentTypeOrder;

            IList<SPContentType> m_new_order = new List<SPContentType>();

            foreach (SPContentType t_ct in m_ct_current_order)
            {
                if (p_ct_name == t_ct.Name)
                {
                    m_new_order.Add(t_ct);
                }
            }

            foreach (SPContentType t_ct in m_ct_current_order)
            {
                if (p_ct_name != t_ct.Name)
                {
                    m_new_order.Add(t_ct);
                }
            }


            p_list.RootFolder.UniqueContentTypeOrder = m_new_order;

            p_list.RootFolder.Update();
        }

        public static void DeleteContentTypeFromList(SPList p_list, string p_ct_name)
        {
            IList<SPContentType> m_ct_current_order = new List<SPContentType>();
            m_ct_current_order = p_list.RootFolder.ContentTypeOrder;

            IList<SPContentType> m_new_order = new List<SPContentType>();

            foreach (SPContentType t_ct in m_ct_current_order)
            {
                if (p_ct_name != t_ct.Name)
                {
                    m_new_order.Add(t_ct);
                }
            }


            p_list.RootFolder.UniqueContentTypeOrder = m_new_order;

            p_list.RootFolder.Update();
        }

        public static void DeleteFormFile(SPWeb p_web, string p_file_url)
        {
            p_web.AllowUnsafeUpdates = true;

            SPFile m_file = p_web.GetFile(p_file_url);

            m_file.Delete();

            p_web.AllowUnsafeUpdates = false;
        }

        public static void DeleteCTFromListAndWeb(string p_ct_name, SPList p_list, SPWeb p_web)
        {
            SPContentType m_ct = p_web.ContentTypes[p_ct_name];

            SPContentType m_list_ct = p_list.ContentTypes[p_ct_name];

            string m_form_name = NameSpaceConstants.FormPrefix + p_ct_name;


            SPContentType m_form_ct = p_web.ContentTypes[m_form_name];
            if (m_list_ct != null)
            {
                ChangeSpecialItemContentType(p_list, m_list_ct);

                m_list_ct.Delete();
            }

            if (m_ct != null)
            {
                //IList<SPContentTypeUsage> usages = SPContentTypeUsage.GetUsages(m_ct);

                m_ct.Delete();
            }
            if (m_form_ct != null)
            {
                m_form_ct.Delete();
            }
        }

        public static void ChangeSpecialItemContentType(SPList p_list, SPContentType p_ct)
        {
            SPListItemCollection m_item_collection = p_list.Items;

            foreach (SPListItem t_item in m_item_collection)
            {
                if (t_item.ContentTypeId.Equals(p_ct.Id))
                {
                    SPContentType m_parent_ct = p_ct.Parent.Parent;//第一个Parent是Web里的ContentType 第二个继承自...的CT
                    SPContentType listCt = p_list.ContentTypes[m_parent_ct.Name];

                    t_item["ContentTypeId"] = listCt.Id.ToString();

                    t_item.Update();
                }
            }
        }

        public static string GetMulitTextString(string p_field_string)
        {
            string m_comment = string.Empty;
            try
            {
                XmlDocument m_doc = new XmlDocument();
                m_doc.LoadXml(p_field_string);

                XmlElement m_xe = m_doc.DocumentElement;
                if (!string.IsNullOrEmpty(m_xe.InnerText))
                {
                    m_comment = m_xe.InnerText;
                }

            }
            catch { }

            return m_comment;
        }

        public static List<string> GetStringListFromChoiceField(SPFieldChoice choiceField)
        {
            List<string> choices = new List<string>();
            foreach (string choice in choiceField.Choices)
            {
                choices.Add(choice);
            }
            return choices;
        }

        public static List<string> GetStringListFromChoiceField(SPFieldMultiChoice choiceField)
        {
            List<string> choices = new List<string>();
            foreach (string choice in choiceField.Choices)
            {
                choices.Add(choice);
            }
            return choices;
        }
    }
}